package main

import (
	"fmt"
	"time"
)

type Pool struct {
	Queue chan func() error
	RuntimeNumber int
	Total int
	Result chan error
	FinishCallback func()
}
// 初始化
func (selfParams *Pool) Init (runtimeNumber int, total int) {
	selfParams.RuntimeNumber = runtimeNumber
	selfParams.Total = total
	selfParams.Queue = make(chan func() error, total)
	selfParams.Result = make(chan error, total)
}

func (selfParams *Pool) Start()  {
	// 开启number goruntine
	for i:=0; i<selfParams.RuntimeNumber; i++ {
		go func() {
			for {
				task, err := <- selfParams.Queue
				if !err {
					fmt.Println("task channel 获取失败")
					break
				}
				errp := task()
				selfParams.Result <- errp
			}
		}()
	}
	// 获取每个任务的处理结果
	for j:=0; j<selfParams.RuntimeNumber; j++ {
		res, ok := <- selfParams.Result
		if !ok {
			fmt.Println("job channel 获取失败")
			break
		}
		if res != nil {
			fmt.Println(res)
		}
	}
	// 结束返回 回调函数
	if selfParams.FinishCallback != nil {
		selfParams.FinishCallback()
	}
}

// 关闭
func (selfParams *Pool) Stop()  {
	close(selfParams.Queue)
	close(selfParams.Result)
}

// 添加任务
func (selfParams *Pool) AddTask(task func() error)  {
	selfParams.Queue <- task
}

// 设置回调函数
func (selfParams *Pool) SetFinishCallback(fff func())  {
	selfParams.FinishCallback = fff
}

// task
func Download(url string) error {
	time.Sleep(time.Second * 1)
	fmt.Println("Download ",url)
	return nil
}
func DownloadFinish()  {
	fmt.Println("Download Finish")
}

func main() {
	var p Pool
	url := []string{"11111","22222","33333","444444","55555","66666","77777","88888","999999"}
	p.Init(9, len(url))

	for i := range url{
		u := url[i]
		p.AddTask(func() error {
			return Download(u)
		})
	}

	p.SetFinishCallback(DownloadFinish)
	p.Start()
	p.Stop()
}
